package io.finer.erp.jeecg.stock.service.impl;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import io.finer.erp.jeecg.bas.mapper.BasMaterialCategoryMapper;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.FillRuleUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.api.client.util.Maps;
import com.google.common.collect.Lists;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import freemarker.template.utility.StringUtil;
import io.finer.erp.jeecg.bas.entity.BasCustomer;
import io.finer.erp.jeecg.bas.entity.BasMaterial;
import io.finer.erp.jeecg.bas.entity.BasMaterialCategory;
import io.finer.erp.jeecg.bas.entity.BasMaterialTemp;
import io.finer.erp.jeecg.bas.entity.BasMeasureUnit;
import io.finer.erp.jeecg.bas.entity.BasProductFormula;
import io.finer.erp.jeecg.bas.entity.BasSupplier;
import io.finer.erp.jeecg.bas.entity.BasWarehouse;
import io.finer.erp.jeecg.bas.entity.ZrkOrderProcess;
import io.finer.erp.jeecg.bas.entity.ZrkOrderProduct;
import io.finer.erp.jeecg.bas.entity.ZrkQzOrder;
import io.finer.erp.jeecg.bas.entity.ZrkShoporder;
import io.finer.erp.jeecg.bas.entity.ZzDevice;
import io.finer.erp.jeecg.bas.entity.ZzDeviceType;
import io.finer.erp.jeecg.bas.entity.ZzShoporder;
import io.finer.erp.jeecg.bas.service.IBasCustomerService;
import io.finer.erp.jeecg.bas.service.IBasMaterialCategoryService;
import io.finer.erp.jeecg.bas.service.IBasMaterialService;
import io.finer.erp.jeecg.bas.service.IBasMaterialTempService;
import io.finer.erp.jeecg.bas.service.IBasMeasureUnitService;
import io.finer.erp.jeecg.bas.service.IBasProductFormulaService;
import io.finer.erp.jeecg.bas.service.IBasSupplierService;
import io.finer.erp.jeecg.bas.service.IBasWarehouseService;
import io.finer.erp.jeecg.bas.service.IZrkOrderProcessService;
import io.finer.erp.jeecg.bas.service.IZrkOrderProductService;
import io.finer.erp.jeecg.bas.service.IZrkQzOrderService;
import io.finer.erp.jeecg.bas.service.IZzDeviceService;
import io.finer.erp.jeecg.bas.service.IZzDeviceTypeService;
import io.finer.erp.jeecg.bas.service.IZzShoporderService;
import io.finer.erp.jeecg.stock.entity.ErpSysUser;
import io.finer.erp.jeecg.stock.entity.IoEntryDTO;
import io.finer.erp.jeecg.stock.entity.ShopOrderToCheck;
import io.finer.erp.jeecg.stock.entity.StkInventory;
import io.finer.erp.jeecg.stock.entity.StkIoBill;
import io.finer.erp.jeecg.stock.entity.StkIoBillEntry;
import io.finer.erp.jeecg.stock.entity.StkIoMaterialLog;
import io.finer.erp.jeecg.stock.entity.StkPickUpBill;
import io.finer.erp.jeecg.stock.entity.StkPickUpEntry;
import io.finer.erp.jeecg.stock.entity.StkProcessingOrder;
import io.finer.erp.jeecg.stock.entity.StkProcessingRecord;
import io.finer.erp.jeecg.stock.entity.StkTray;
import io.finer.erp.jeecg.stock.entity.StkTrayDetail;
import io.finer.erp.jeecg.stock.mapper.ErpUserMapper;
import io.finer.erp.jeecg.stock.mapper.ScanMapper;
import io.finer.erp.jeecg.stock.mapper.StkIoBillEntryMapper;
import io.finer.erp.jeecg.stock.mapper.StkIoBillMapper;
import io.finer.erp.jeecg.stock.service.IScan2ndService;
import io.finer.erp.jeecg.stock.service.IScanService;
import io.finer.erp.jeecg.stock.service.IStkInventoryService;
import io.finer.erp.jeecg.stock.service.IStkIoBillEntryService;
import io.finer.erp.jeecg.stock.service.IStkIoBillService;
import io.finer.erp.jeecg.stock.service.IStkIoMaterialLogService;
import io.finer.erp.jeecg.stock.service.IStkPickUpBillService;
import io.finer.erp.jeecg.stock.service.IStkPickUpEntryService;
import io.finer.erp.jeecg.stock.service.IStkProcessingOrderService;
import io.finer.erp.jeecg.stock.service.IStkProcessingRecordService;
import io.finer.erp.jeecg.stock.service.IStkTrayDetailService;
import io.finer.erp.jeecg.stock.service.IStkTrayService;
import io.finer.erp.jeecg.stock.util.ScanUtil;
import io.finer.erp.jeecg.stock.vo.CompanyModel;
import io.finer.erp.jeecg.stock.vo.InventoryVo;
import io.finer.erp.jeecg.stock.vo.ScanIO;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class Scan2ndService implements IScan2ndService{
	@Autowired
	private IStkIoMaterialLogService ioLogService;
	@Autowired
	private ScanMapper scanMapper;
	@Autowired
	private ErpUserMapper userMapper;
	@Autowired
	private IBasMaterialTempService materialTempService;
	@Autowired
	private IZrkOrderProcessService processService;
	@Autowired
	private IStkIoBillEntryService billEntryService;
	@Autowired
	private IStkIoBillService billService;
	@Autowired
	private IBasMaterialService materialService;
	@Autowired
	private IStkIoMaterialLogService logService;
	@Autowired
	private IBasMeasureUnitService unitService;
	@Autowired
	private IStkInventoryService inventoryService;
	@Autowired
	private IZzShoporderService shopOrderService;
	@Autowired
	private IBasMaterialCategoryService categoryService;
	@Autowired
	private IStkPickUpBillService pickUpBillService;
	@Autowired
	private IStkPickUpEntryService pickUpEntryService;
	@Autowired
	private IZzDeviceTypeService deviceTypeService;
	@Autowired
	private IZrkOrderProductService orderProductService;
	@Autowired
	private IScanService scanService;
	@Autowired
	private IBasWarehouseService warehouseService;
	@Autowired
	private IZzDeviceService deviceService;
	@Autowired
	private IBasCustomerService customerService;
	@Autowired
	private IBasSupplierService supplierService;
	@Autowired
	private IZrkQzOrderService mesService;
	@Autowired
	private StkIoBillEntryMapper stkIoBillEntryMapper;
	@Autowired
	private IBasProductFormulaService formulaService;
	@Autowired
	private IStkTrayService trayService;
	@Autowired
	private IStkTrayDetailService trayDetailService;
	@Autowired
	private StkIoBillMapper billMapper;
	@Autowired
	private IStkProcessingOrderService processingOrderService;
	@Autowired
	private IStkProcessingRecordService processingRecordService;
	@Autowired
	private ISysBaseAPI basApi;
	@Autowired
	private BasMaterialCategoryMapper basMaterialCategoryMapper;
	
	private static final String PROCESSING_ORDER_TYPE = "stk_io_bill..301";
	private static final String PROCESSING_ORDER_ENTRY_TYPE = "stk_io_bill.stk_io_bill_entry.301";
//	private static final String BILL_STATUS = "12";
	private static final String BILL_SUBMIT_STATUS = "13";
	private static final String BILL_STATUS_APPROVAL = "23";
	private final List<String> inTypes = Arrays.asList("101", "1011", "199", "1991", "1993", "1992", "1994", "1997", "1995");
	private final List<String> outTypes = Arrays.asList("201", "299", "2011", "2991", "2992", "2993", "2997");

	@Override
	public BigDecimal getMaterialCost(StkIoMaterialLog ioLog) {
		String type = ioLog.getIoType();
		if(type == null) {
			return null;
		}
		List<StkIoMaterialLog> logList = ioLogService.getByProcess(ioLog.getProcedureId());
		if(logList == null || logList.size() == 0) {
			return null;
		}
		if("1994".equals(type)) {//原材料入库
			String materialId = ioLog.getMaterialId();
			for (StkIoMaterialLog stkIoMaterialLog : logList) {
				//找到该原材料的出库记录，并根据其入库数量计算剩余成本
				if(materialId.equals(stkIoMaterialLog.getMaterialId())) {
					String logType = stkIoMaterialLog.getIoType();
					if(outTypes.contains(logType)) {
						BigDecimal num = ioLog.getAmount();
						BigDecimal preNum = stkIoMaterialLog.getAmount();
						BigDecimal preCost = stkIoMaterialLog.getCost();
						if(null == preCost) {
							preCost = BigDecimal.ZERO;
						}
						BigDecimal cost = num.multiply(preCost).divide(preNum, 2, BigDecimal.ROUND_DOWN);
						return cost;
					}
				}
			}
		}
		if("1992".equals(type) || "1993".equals(type) || "1991".equals(type)) {
			//先判断有没有其他物料入库，如果有，此物料与其他物料分成本，如果没有则该物料独享成本。
			List<StkIoMaterialLog> list = Lists.newArrayList();
			//计算该工序的总成本
			BigDecimal totalCost = BigDecimal.ZERO;
			for (StkIoMaterialLog stkIoMaterialLog : logList) {
				String ioType = stkIoMaterialLog.getIoType();
				BigDecimal ioCost = stkIoMaterialLog.getCost();
				if(null == ioCost) {
					ioCost = BigDecimal.ZERO;
				}
				if(type.equals(ioType)) {
					list.add(stkIoMaterialLog);
				} else if(inTypes.contains(ioType)) {
					totalCost = totalCost.subtract(ioCost);
				} else if(outTypes.contains(ioType)) {
					totalCost = totalCost.add(ioCost);
				}
			}
			if(list.size() == 0) {
				return totalCost;
			}
			BigDecimal cost;
			BigDecimal square = ioLog.getSquare();
			if(square == null) {
				BigDecimal width = ioLog.getWidth();
				BigDecimal length = ioLog.getLength();
				if(width != null && length != null) {
					square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length);
				}
			}
			//计算总平方数
			BigDecimal totalSquare = BigDecimal.ZERO;
			for (StkIoMaterialLog log : list) {
				BigDecimal preSquare = log.getSquare();
				if(null == preSquare) {
					BigDecimal width = log.getWidth();
					BigDecimal length = log.getLength();
					if(width != null && length != null) {
						preSquare = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length);
						log.setSquare(preSquare);
						this.ioLogService.updateById(log);
					} else {
						preSquare = BigDecimal.ZERO;
					}
					log.setSquare(preSquare);
				}
				totalSquare = totalSquare.add(preSquare);
			}
			totalSquare = totalSquare.add(square);
			//根据现有的总平方数和各个物料的平方数计算各个物料的成本
			for (StkIoMaterialLog log : list) {
				BigDecimal eachSquare = log.getSquare();
				String entryId = log.getEntityId();
				StkIoBillEntry entry = billEntryService.getById(entryId);
				if(entry == null) {
					continue;
				}
				BigDecimal eachCost = eachSquare.multiply(totalCost).divide(totalSquare, 2, BigDecimal.ROUND_DOWN);
				log.setCost(eachCost);
				entry.setCost(eachCost);
				this.billEntryService.updateById(entry);//更新出入库信息
				this.ioLogService.updateById(log);//更新出入库日志信息
				this.inventoryService.updateProductInCost(entry);//更新实时库存的成本
			}
			cost = square.multiply(totalCost).divide(totalSquare, 2, BigDecimal.ROUND_DOWN);
			return cost;
		}
		return null;
	}

	@Override
	public Result<?> getProcessingOrder() {
		List<InventoryVo> list = scanMapper.getProcessingOrder();
		return Result.ok(list);
	}

	@Override
	public Result<JSONObject> processingIn(ScanIO scanIo, Result<JSONObject> result) {
		String userId = scanIo.getUserId();
		String userName = scanIo.getUserName();
		String orgCode = scanIo.getOrgCode();
		String listStr = scanIo.getList();
		String warehouseId = scanIo.getWarehouseId();
		if(StringUtils.isBlank(warehouseId)) {
			return result.error500("请选择仓库。");
		}
		if(StringUtils.isBlank(listStr)) {
			return result.error500("请扫描物料码");
		}
		JSONArray listArray = JSON.parseArray(listStr);
		if(listArray == null || listArray.size() == 0) {
			return result.error500("未传入物料编码");
		}
		List<String> codes = CollUtil.newArrayList();
		for(int i = 0; i < listArray.size(); i++) {
			JSONObject jsonObject = listArray.getJSONObject(i);
			String codeStr = jsonObject.getString("code");
			if(StringUtils.isNotBlank(codeStr)) {
				codes.add(codeStr);
			}
		}
		if(codes.isEmpty()) {
			return result.error500("未传入物料编码");
		}
		List<BasMaterialTemp> temps = this.materialTempService.getByCodes(codes);
		if(CollUtil.isEmpty(temps)) {
			return result.error500("未查找到物料");
		}
		Map<String, List<BasMaterial>> processingMaterialMap = Maps.newHashMap();
		Map<String, BasMaterialTemp> tempMap = Maps.newHashMap();
		Map<String, BasMaterial> materialMap = Maps.newHashMap();
		for (BasMaterialTemp temp : temps) {
			String code = temp.getCode();
			String processingId = temp.getProcessingId();
			if(StringUtils.isBlank(processingId)) {
				return result.error500("编码为" + temp.getCode() + "的物料没有选择代加工单");
			}
			tempMap.put(temp.getCode(), temp);
			BasMaterial material = this.materialService.getMaterialByCode(code);
			if(null == material) {
				material = this.materialTempService.tempToMaterial(code);
				if(null == material) {
					return result.error500(new StringBuffer("").append("编码为").append(code).append("的物料未找到").toString());
				}
			}
			List<BasMaterial> list = processingMaterialMap.get(processingId);
			if(null == list) {
				list = CollUtil.newArrayList(material);
				processingMaterialMap.put(processingId, list);
			} else {
				list.add(material);
			}
			materialMap.put(material.getId(), material);
		}
		if(CollUtil.isEmpty(materialMap.keySet())) {
			return result.error500("未查找到物料");
		}
		int count = this.billEntryService.lambdaQuery().in(StkIoBillEntry::getMaterialId, materialMap.keySet()).count();
		if(count > 0) {
			return result.error500("不能重复提交");
		}
		Date date = DateUtils.getDate();
		Map<StkIoBill, List<StkIoBillEntry>> billMap = Maps.newHashMap();
		for(String processingId : processingMaterialMap.keySet()) {
			StkProcessingOrder processingOrder = this.processingOrderService.getById(processingId);
			if(null == processingOrder) {
				return result.error500("未找到代加工单");
			}
			
			String billNo = basApi.getNoByCode("stock_io_bill_no");
			StkIoBill bill = new StkIoBill();
			bill.setBillNo(billNo);
			bill.setStockIoType(scanIo.getOperType());
			bill.setBillDate(date);
			bill.setIsAuto(1);
			bill.setClerkId(userName);
			bill.setHandlerId(userName);
			bill.setIsApproved(1);
			bill.setCreateBy(userName);
			bill.setCreateTime(date);
			bill.setIsRubric(0);
			bill.setHasRp(1);
			bill.setSourceType(PROCESSING_ORDER_TYPE);
			bill.setSourceId(processingOrder.getId());
			bill.setSourceNo(processingOrder.getOrderNo());
			bill.setBillProcStatus(BILL_STATUS_APPROVAL);
			bill.setSysOrgCode(scanIo.getOrgCode());
			bill.setSupplierId(processingOrder.getSupplierId());
			
			List<BasMaterial> list = processingMaterialMap.get(processingId);
			int num = 1;
			List<StkIoBillEntry> entryList = Lists.newLinkedList();
			for(BasMaterial material : list) {
				String code = material.getCode();
				BasMaterialTemp temp = tempMap.get(code);
				BigDecimal amount = null;
				BigDecimal width = null;
				BigDecimal length = null;
				if(temp != null) {
					amount = temp.getAmount();
					width = temp.getWidth();
					length = temp.getLength();
				}
				
				StkIoBillEntry billEntry = new StkIoBillEntry();
				int batch = num * 10;
				billEntry.setMaterialId(material.getId());
				billEntry.setBillNo(billNo);
				billEntry.setMid(bill.getId());
				billEntry.setBatchNo(billNo + "-" + batch);
				billEntry.setQty(amount);
				billEntry.setSourceType(bill.getSourceType());
				if(null != width) {
					billEntry.setWidth(width);
				}
				if(null != length) {
					billEntry.setLength(length);
				}
				billEntry.setUnitId(material.getUnitId());
				billEntry.setWarehouseId(warehouseId);
				billEntry.setSettleQty(amount);
				billEntry.setEntryNo(num);
				billEntry.setCost(BigDecimal.ZERO);
				billEntry.setSettlePrice(BigDecimal.ZERO);
				billEntry.setSettleAmt(BigDecimal.ZERO);
				billEntry.setSettleQty(BigDecimal.ZERO);
				billEntry.setSupplierId(processingOrder.getSupplierId());
				billEntry.setSourceType(PROCESSING_ORDER_ENTRY_TYPE);
				billEntry.setBillNo(bill.getBillNo());
				entryList.add(billEntry);
				num++;
			}
			billMap.put(bill, entryList);
		}
		for (StkIoBill bill : billMap.keySet()) {
			List<StkIoBillEntry> list = billMap.get(bill);
			
			this.billService.saveMain(bill, list);
			this.billService.updateInventory(bill, list);
			for (StkIoBillEntry entry : list) {
				String materialId = entry.getMaterialId();
				BasMaterial material = materialMap.get(materialId);
				if(null != material) {
					logService.insertLog(bill.getId(), date, entry.getId()
							, scanIo.getOperType(), 0, material
							, material.getUnitId(), bill.getSourceId(), 1
							, BigDecimal.ZERO, BigDecimal.ZERO, entry.getId());
				}
			}
			log.info("代加工入库完成" + bill.getBillNo());
		}
		//最后一次提交时 计算成本
		String isFinal = scanIo.getIsFinal();
		if(null != isFinal && "是".equals(isFinal)) {
			List<String> processingIdList = Lists.newArrayList();
			for (StkIoBill bill : billMap.keySet()) {
				String processingId = bill.getSourceId();
				processingIdList.add(processingId);
			}
			for(String processingId : processingIdList) {
				List<StkProcessingRecord> records = processingRecordService.selectByMainId(processingId);
				if(null == records) {
					continue;
				}
				//根据代加工单详情获取加工单价
				Map<String, BigDecimal> categorySiglePriceMap = Maps.newLinkedHashMap();
				for(Iterator<StkProcessingRecord> it = records.iterator(); it.hasNext();) {
					StkProcessingRecord record = it.next();
					String inCategoryId = record.getInCategoryId();
					BigDecimal price = record.getProcessingAmount();
					categorySiglePriceMap.put(inCategoryId, price);
				}
				//获取该代加工单的出库单信息及出库单详情
				List<StkIoBill> billList = billService.lambdaQuery().eq(StkIoBill::getSourceId, processingId).eq(StkIoBill::getStockIoType, "3995").list();
				if(CollUtil.isEmpty(billList)) {
					continue;
				}
				List<String> billIdList = Lists.newLinkedList();
				for(StkIoBill bill : billList) {
					billIdList.add(bill.getId());
				}
				List<StkIoBillEntry> entryList = billEntryService.lambdaQuery().in(StkIoBillEntry::getMid, billIdList).list();
				if(CollUtil.isEmpty(entryList)) {
					continue;
				}
				//按物料分类封装物料出库成本
				Map<String, BigDecimal> outCategoryCostMap = Maps.newHashMap();
				List<String> queryMIds = Lists.newArrayList();
				for(Iterator<StkIoBillEntry> it = entryList.iterator(); it.hasNext();) {
					StkIoBillEntry entry = it.next();
					queryMIds.add(entry.getMaterialId());
				}
				List<BasMaterial> outMaterialList = materialService.getByIds(queryMIds);
				Map<String, String> outMaterialCategoryMap = Maps.newHashMap();
				for(Iterator<BasMaterial> it = outMaterialList.iterator(); it.hasNext();) {
					BasMaterial material = it.next();
					String cateId = material.getCategoryId();
					String materialId = material.getId();
					outMaterialCategoryMap.put(materialId, cateId);
				}
				for(Iterator<StkIoBillEntry> it = entryList.iterator(); it.hasNext();) {
					StkIoBillEntry entry = it.next();
					String materialId = entry.getMaterialId();
					String categoryId = outMaterialCategoryMap.get(materialId);
					BigDecimal decimal = outCategoryCostMap.get(categoryId);
					if(null == decimal) {
						outCategoryCostMap.put(categoryId, entry.getCost());
					} else {
						BigDecimal cost = entry.getCost();
						decimal = decimal.add(cost);
						outCategoryCostMap.put(categoryId, decimal);
					}
				}
				//按照入库物料计算物料加工总价
				List<StkIoBill> inBillList = billService.lambdaQuery().eq(StkIoBill::getSourceId, processingId).eq(StkIoBill::getStockIoType, "1995").list();
				if(CollUtil.isEmpty(inBillList)) {
					continue;
				}
				List<String> inBillIdList = Lists.newArrayList();
				for(StkIoBill bill : inBillList) {
					inBillIdList.add(bill.getId());
				}
				List<StkIoBillEntry> inEntryList = billEntryService.lambdaQuery().in(StkIoBillEntry::getMid, inBillIdList).list();
				queryMIds = Lists.newArrayList();
				Map<String, String> inMaterialCategoryMap = Maps.newHashMap();
				for(StkIoBillEntry entry : inEntryList) {
					String materialId = entry.getMaterialId();
					queryMIds.add(materialId);
				}
				List<BasMaterial> inMaterialList = this.materialService.getByIds(queryMIds);
				for (BasMaterial material : inMaterialList) {
					inMaterialCategoryMap.put(material.getId(), material.getCategoryId());
				}
				Map<String, BigDecimal> inCategoryQtyMap = Maps.newHashMap();
				for(StkIoBillEntry entry : inEntryList) {
					String materialId = entry.getMaterialId();
					String categoryId = inMaterialCategoryMap.get(materialId);
					BigDecimal qty = entry.getQty();
					BigDecimal decimal = inCategoryQtyMap.get(categoryId);
					if(null == decimal) {
						inCategoryQtyMap.put(categoryId, qty);
					} else {
						decimal = decimal.add(qty);
						inCategoryQtyMap.put(categoryId, decimal);
					}
				}
				BigDecimal totalProcessingMoney = BigDecimal.ZERO;//该代加工单总的加工金额
				Map<String, BigDecimal> inCategoryAmountMap = Maps.newHashMap();
				for(String cateId : inCategoryQtyMap.keySet()) {
					BigDecimal unitPrice = categorySiglePriceMap.get(cateId);
					BigDecimal qty = inCategoryQtyMap.get(cateId);
					if(null != qty && null != unitPrice) {
						BigDecimal categoryAmount = unitPrice.multiply(qty);
						totalProcessingMoney = totalProcessingMoney.add(categoryAmount);
						inCategoryAmountMap.put(cateId, categoryAmount);
					}
				}
				//计算出库物料跟入库物料的对应比例
				Map<String, List<String>> recordCateMap = Maps.newHashMap();
				for (StkProcessingRecord record : records) {
					String out = record.getOutCategoryId();
					String in = record.getInCategoryId();
					
					List<String> list = recordCateMap.get(out);
					if(null == list) {
						list = CollUtil.newArrayList(in);
						recordCateMap.put(out, list);
					} else {
						list.add(in);
					}
				}
				Map<String, StkProcessingRecord> recordMap = Maps.newHashMap();
				List<String> categoryIds = Lists.newArrayList();
				Map<String, List<StkProcessingRecord>> outCateRecordMap = Maps.newHashMap();
				for (StkProcessingRecord record : records) {
					recordMap.put(record.getId(), record);
					String inCategoryId = record.getInCategoryId();
					String outCategoryId = record.getOutCategoryId();
					categoryIds.add(inCategoryId);
					categoryIds.add(outCategoryId);
					List<StkProcessingRecord> list = outCateRecordMap.get(outCategoryId);
					if(null == list) {
						list = CollUtil.newArrayList(record);
						outCateRecordMap.put(outCategoryId, list);
					} else {
						list.add(record);
					}
				}
				List<BasMaterialCategory> categorys = this.categoryService.lambdaQuery().in(BasMaterialCategory::getId, categoryIds).list();
				Map<String, BasMaterialCategory> categoryMap = Maps.newHashMap();
				List<String> unitIds = Lists.newArrayList();
				for(BasMaterialCategory category : categorys) {
					categoryMap.put(category.getId(), category);
					if(StringUtils.isNotBlank(category.getUnitId())) {
						unitIds.add(category.getUnitId());
					}
				}
				List<BasMeasureUnit> units = this.unitService.lambdaQuery().in(BasMeasureUnit::getId, unitIds).list();
				Map<String, BasMeasureUnit> unitMap = Maps.newHashMap();
				for(BasMeasureUnit unit : units) {
					unitMap.put(unit.getId(), unit);
				}
				Map<String, List<ProcessingOutPercent>> outPercentMap = Maps.newHashMap();
				for(String key : recordCateMap.keySet()) {
					List<String> list = recordCateMap.get(key);
					if(list.size() == 1) {
						ProcessingOutPercent percent = new ProcessingOutPercent();
						percent.setCategoryId(list.get(0));
						percent.setPercent(BigDecimal.ONE);
						outPercentMap.put(key, CollUtil.newArrayList(percent));
					} else if(list.size() > 1){
						//TODO
						List<StkProcessingRecord> recordList = outCateRecordMap.get(key);
						BigDecimal totalDecimal = BigDecimal.ZERO;
						Boolean flag = true;
						Map<String, BigDecimal> inDecimalMap = Maps.newHashMap();
						for(StkProcessingRecord record : recordList) {
							String outModel = record.getOutModel();
							String[] strs = StringUtils.split(outModel, "*");
							BigDecimal outCount = record.getOutCount();
							if(null == outCount) {
								flag = false;
								break;
							}
							if(strs.length <= 1) {
								flag = false;
								break;
							}
							if(!NumberUtil.isNumber(strs[0]) || !NumberUtil.isNumber(strs[1])) {
								flag = false;
								break;
							}
							BigDecimal width = new BigDecimal(strs[0]).divide(new BigDecimal("100"), 6, BigDecimal.ROUND_DOWN);
							BigDecimal length = new BigDecimal(strs[1]);
							String inCategoryId = record.getInCategoryId();
							BigDecimal bigDecimal = inDecimalMap.get(inCategoryId);
							BigDecimal number = width.multiply(length).multiply(outCount);
							if(null == bigDecimal) {
								number = number.setScale(4, BigDecimal.ROUND_DOWN);
								inDecimalMap.put(inCategoryId, number);
							} {
								bigDecimal = bigDecimal.add(number);
								bigDecimal = bigDecimal.setScale(4, BigDecimal.ROUND_DOWN);
								inDecimalMap.put(inCategoryId, bigDecimal);
							}
							totalDecimal = totalDecimal.add(number);
						}
						if(!flag) {
							totalDecimal = BigDecimal.ZERO;
							inDecimalMap = Maps.newHashMap();
							for(StkProcessingRecord record : recordList) {
								BigDecimal outCount = record.getOutCount();
								if(null == outCount) {
									outCount = BigDecimal.ZERO;
								}
								String inCategoryId = record.getInCategoryId();
								BigDecimal bigDecimal = inDecimalMap.get(inCategoryId);
								BigDecimal number = outCount;
								if(null == bigDecimal) {
									number = number.setScale(4, BigDecimal.ROUND_DOWN);
									inDecimalMap.put(inCategoryId, number);
								} {
									bigDecimal = bigDecimal.add(number);
									bigDecimal = bigDecimal.setScale(4, BigDecimal.ROUND_DOWN);
									inDecimalMap.put(inCategoryId, bigDecimal);
								}
								totalDecimal = totalDecimal.add(number);
							}
						}
						List<ProcessingOutPercent> percentList = Lists.newArrayList();
						for (String in : list) {
							ProcessingOutPercent per = new ProcessingOutPercent();
							percentList.add(per);
							per.setCategoryId(in);
							BigDecimal bigDecimal = inDecimalMap.get(in);
							if(null == bigDecimal) {
								bigDecimal = BigDecimal.ZERO;
							}
							BigDecimal percent = bigDecimal.divide(totalDecimal, 4, BigDecimal.ROUND_DOWN);
							per.setPercent(percent);
						}
						outPercentMap.put(key, percentList);
					}
				}
				//计算入库物料的总成本
				Map<String, BigDecimal> totalInCostMap = Maps.newHashMap();
				for(String key : outPercentMap.keySet()) {
					List<ProcessingOutPercent> list = outPercentMap.get(key);
					if(null == list) {
						continue;
					}
					for(ProcessingOutPercent percent : list) {
						String categoryId = percent.getCategoryId();
						BigDecimal decimal = percent.getPercent();
						
						BigDecimal bigDecimal = outCategoryCostMap.get(key);
						if(null == bigDecimal) {
							continue;
						}
						BigDecimal cost = bigDecimal.multiply(decimal);
						BigDecimal inCost = totalInCostMap.get(categoryId);
						if(null == inCost) {
							totalInCostMap.put(categoryId, cost);
						} else {
							inCost = inCost.add(cost);
							totalInCostMap.put(categoryId, inCost);
						}
					}
				}
				//计算代加工入库时物料成本
				for(StkIoBillEntry entry : inEntryList) {
					String materialId = entry.getMaterialId();
					String categoryId = inMaterialCategoryMap.get(materialId);
					BigDecimal totalCost = totalInCostMap.get(categoryId);
					BigDecimal totalAmount = inCategoryAmountMap.get(categoryId);
					BigDecimal qty = entry.getQty();
					BigDecimal totalQty = inCategoryQtyMap.get(categoryId);
					if(null == totalCost || null == totalAmount || null == qty || null == totalQty) {
						continue;
					}
					BigDecimal entryCost = totalCost.multiply(qty).divide(totalQty, 2, BigDecimal.ROUND_DOWN);
					BigDecimal entryAmount = totalAmount.multiply(qty).divide(totalQty, 2, BigDecimal.ROUND_DOWN);
					BigDecimal cost = entryCost.add(entryAmount);
					entry.setCost(cost);
					this.billEntryService.updateById(entry);
					StkIoBill byMaterialId = billService.getByMaterialId(materialId);
					if(byMaterialId != null) {
						String stockIoType = byMaterialId.getStockIoType();
						if("1995".equals(stockIoType)) {
							String batchNo = entry.getBatchNo();
							StkInventory inventory = inventoryService.selectByWarehouseAndMaterial(warehouseId, materialId);
							if(null != inventory && batchNo.equals(inventory.getBatchNo())) {
								inventory.setCost(cost);
								this.inventoryService.updateById(inventory);
							}
						}
					}
				}
				
				StkProcessingOrder order = this.processingOrderService.getById(processingId);
				order.setOrderStatus("5");
				order.setTotalAmount(totalProcessingMoney);
				this.processingOrderService.updateById(order);
			}
		} else {
			List<String> processingIdList = Lists.newArrayList();
			for (StkIoBill bill : billMap.keySet()) {
				String processingId = bill.getSourceId();
				processingIdList.add(processingId);
			}
			for(String processingId : processingIdList) {
				StkProcessingOrder order = this.processingOrderService.getById(processingId);
				String status = order.getOrderStatus();
				if("5".equals(status)) {
					continue;
				}
				order.setOrderStatus("4");
				this.processingOrderService.updateById(order);
			}
		}
		
		return result.success("入库成功");
	}

	@Override
	public List<CompanyModel> getCompany() {
		List<CompanyModel> list = scanMapper.getCompany("EXPRESSNAME");
		if(list == null || list.size() == 0) {
			return null;
		}
		int index = 0;
		for (int i = 0; i < list.size(); i++) {
			if("1".equals(list.get(i).getValue())) {
				index = i;
			}
		}
		list.remove(index);
		return list;
	}
	
	@Override
	public Result<?> productInfo(ScanIO scanIo) {
		//判断传入数据是否准确
		String orderId = scanIo.getOrderNum();
		String procedureId = scanIo.getProcedureId();
		String categoryId = scanIo.getCategoryId();
		BigDecimal width = scanIo.getWidth();
		BigDecimal length = scanIo.getLength();
		Integer knife = scanIo.getKnife();
		BigDecimal amount = scanIo.getAmount();
		String labelId = scanIo.getLabelId();
		if (length == null) {
			return Result.error("请输入长度。");
		}
		if (width == null) {
			return Result.error("请输入宽度。");
		}
		//TODO
		ZrkQzOrder order = this.mesService.getById(orderId);
		if(null == order) {
			return Result.error("未找到该MES单。");
		}
		if(StringUtils.isBlank(procedureId)) {
			return Result.error("未找到该工序。");
		}
		ZzDeviceType process = deviceTypeService.getById(procedureId);
		if (null == process) {
			return Result.error("未找到该工序。");
		}
		String customerId = scanIo.getCustomerId();
		//查询设备并判断
		String deviceId = order.getMachineId();
		ZzDevice device = this.deviceService.getById(deviceId);
		String mathineName = "";
		if(null != device) {
			mathineName = device.getDeviceName();
		}
		ZzDeviceType zzDeviceType = process;
		Integer batchNum = scanIo.getBatchNum();
		if(null == batchNum || batchNum <= 0) {
			return Result.error("请输入正确的打印数量。");
		}
		
		//判断是复合、分切还是切张
		boolean fqFlag = false;
		boolean qzFlag = false;
		boolean fhFlag = false;
		if (zzDeviceType.getDeviceTpyeName().contains("复合")){
			fhFlag = true;
		}
		if (zzDeviceType.getDeviceTpyeName().contains("切张")) {
			qzFlag = true;
		}
		if (zzDeviceType.getDeviceTpyeName().contains("分切")) {
			fqFlag = true;
		}
		//如果是复合或者切张
		BasMaterialCategory category = null;
		if(StringUtils.isBlank(categoryId)) {
			return Result.error("请选择分类");
		}
		category = this.categoryService.getById(categoryId);
		if (null == category) {
			return Result.error("物料分类选择错误");
		}
		//需要打印的名称
		String printName = category.getName();
		String materialNo = category.getMaterialNo();
		if(StringUtils.isNotBlank(materialNo)) {
			printName = printName + " " + materialNo;
		}
		//获取操作人员
		String userIds = order.getOperatorUsers();
		String[] userIdArray = StringUtils.split(userIds, ",");
		List<String> workNoList = CollUtil.newLinkedList();
		for (int i = 0; i < userIdArray.length; i++) {
			String userId = userIdArray[i];
			List<ErpSysUser> users = this.userMapper.getUser(userId);
			ErpSysUser user = null;
			if(CollUtil.isEmpty(users)) {
				user = this.userMapper.getUserByUserName(userId);
			} else {
				user = users.get(0);
			}
			if(null != user) {
				workNoList.add(user.getWorkNo());
			}
		}
		String workNo = StringUtils.EMPTY;
		if(CollUtil.isNotEmpty(workNoList)) {
			workNo = CollUtil.join(workNoList, ",");
		}
		
		//封装物料信息
		Date date = DateUtil.date();
		List<BasMaterialTemp> saveList = Lists.newLinkedList();
		//获取配方
		String formulaId = order.getFormulaId();
		BasProductFormula formula = formulaService.getById(formulaId);
		//上级物料维护
		String pids = "";
		String list = scanIo.getList();
		if(StringUtils.isNotBlank(list)) {
			JSONArray jsonArray = JSONObject.parseArray(list);
			if(jsonArray == null || jsonArray.size() == 0) {
				return Result.error("未传入物料编码。");
			}
			List<String> materialCodes = Lists.newArrayList();
			for(int k = 0; k < jsonArray.size(); k++) {
				JSONObject jsonObject = jsonArray.getJSONObject(k);
				String code = jsonObject.getString("code");
				materialCodes.add(code);
			}
			List<BasMaterial> materials = materialService.getByCodes(materialCodes);
			if(null == materials || 0 == materials.size()) {
				return Result.error("根据传入的物料编码，未查询到物料信息。");
			}
			for (BasMaterial mate : materials) {
				pids += mate.getId() + " ";
			}
			pids = StringUtils.replace(pids.trim(), " ", ",");
		}
		
		String preGlue = null;
		String preRoll = null;
		String prePrint = null;
		String preGrams = null;
		Integer preKnife = null;
		if(null == formula) {
			if(fqFlag) {
				String pid = pids;
				if(StringUtils.isNotBlank(pid)) {
					String[] pidArray = StringUtils.split(pid, ",");
					String mPId = pidArray[0];
					BasMaterial mate = this.materialService.getById(mPId);
					if(null != mate) {
						String code = mate.getCode();
						BasMaterialTemp temp = this.materialTempService.getByCode(code);
						formulaId = temp.getFormulaId();
						formula = formulaService.getById(formulaId);
						
						preGlue = temp.getGluePosition();
						preRoll = temp.getRollDirect();
						prePrint = temp.getIsPrint();
						preGrams = temp.getGrams();
					}
				}
			}
			if(qzFlag) {
				String pid = pids;
				if(StringUtils.isNotBlank(pid)) {
					String[] pidArray = StringUtils.split(pid, ",");
					String mPId = pidArray[0];
					BasMaterial mate = this.materialService.getById(mPId);
					if(null != mate) {
						String code = mate.getCode();
						BasMaterialTemp temp = this.materialTempService.getByCode(code);
						formulaId = temp.getFormulaId();
						formula = formulaService.getById(formulaId);
						if(formula == null) {
							pid = temp.getPid();
							if(StringUtils.isNotBlank(pid)) {
								pidArray = StringUtils.split(pid, ",");
								mPId = pidArray[0];
								mate = this.materialService.getById(mPId);
								if(null != mate) {
									code = mate.getCode();
									temp = this.materialTempService.getByCode(code);
									formulaId = temp.getFormulaId();
									formula = formulaService.getById(formulaId);
								}
							}
						}
					}
				}
			}
		}
		
		//封装切张相关参数
		Map<String, String> qzMap = Maps.newHashMap();
		if(qzFlag) {
			String pid = pids;
			if(StringUtils.isNotBlank(pid)) {
				String[] pidArray = StringUtils.split(pid, ",");
				String mPId = pidArray[0];
				BasMaterial mate = this.materialService.getById(mPId);
				if(null != mate) {
					String code = mate.getCode();
					BasMaterialTemp temp = this.materialTempService.getByCode(code);
					if(null != temp) {
						qzMap.put("fqRoll", StringUtils.isBlank(temp.getRollDirect()) ? StringUtils.EMPTY : temp.getRollDirect());
						qzMap.put("fqKnife", temp.getKnifeNum() != null ? temp.getKnifeNum().toString() : StringUtils.EMPTY);
						qzMap.put("fqIn", StringUtils.isBlank(temp.getInspector()) ? StringUtils.EMPTY : temp.getInspector());
						
					}
					
					String pid2 = temp.getPid();
					if(StringUtils.isNotBlank(pid2)) {
						String[] pidArray2 = StringUtils.split(pid2, ",");
						String mPId2 = pidArray2[0];
						BasMaterial mate2 = this.materialService.getById(mPId2);
						if(null != mate2) {
							String code2 = mate2.getCode();
							BasMaterialTemp temp2 = this.materialTempService.getByCode(code2);
							if(null != temp2) {
								qzMap.put("fhRoll", StringUtils.isBlank(temp2.getRollDirect()) ? StringUtils.EMPTY : temp2.getRollDirect());
							}
						}
					}
				}
			}
		}
		
		String unitId = category.getUnitId();
		BasMeasureUnit unit = unitService.getById(unitId);
		
		for(int i = 0; i < batchNum; i ++) {
			String materialCode = this.materialService.getCode(category.getCode());
			BasMaterialTemp material = new BasMaterialTemp();
			material.setCategoryId(category.getId());
			material.setCode(materialCode);
			material.setName(category.getName());
			material.setCreateTime(date);
			material.setLength(length);
			material.setWidth(width);
			material.setUnitId(category.getUnitId());
			material.setOrderId(orderId);
			material.setProcedureId(orderId);
			material.setMachine(deviceId);
			material.setRemark(scanIo.getRemark());
			material.setKnifeNum(knife);
			material.setCustomerId(customerId);
			material.setFormulaId(formulaId);
			material.setPid(pids);
			material.setInspector(workNo);
			if(StringUtils.isNotBlank(labelId)) {
				material.setLabelId(labelId);
			}
			
			BigDecimal square = null;
			if(fhFlag) {
				String grams = scanIo.getGrams();
				String roll = scanIo.getRoll();
				String glue = scanIo.getGlue();
				String print = scanIo.getPrint();
				material.setGrams(grams);
				material.setRollDirect(roll);
				material.setIsPrint(print);
				material.setGluePosition(glue);
				square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length);
			}
			if(fqFlag) {
				String surfaceLayer = scanIo.getSurfaceLayer();
				material.setSupplierId(surfaceLayer);
				square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length);
				String roll = scanIo.getRoll();
				System.out.println(JSON.toJSONString(scanIo));
				material.setRollDirect(roll);
				material.setGrams(preGrams);
				material.setIsPrint(prePrint);
				material.setGluePosition(preGlue);
			}
			if(qzFlag) {
				square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN));
				String numberStr = scanIo.getNumber();
				if(!StringUtils.isBlank(numberStr)) {
					BigDecimal numDecimal = new BigDecimal(numberStr);
					square = square.multiply(numDecimal);
					material.setPageNum(numDecimal);
				}
				material.setGrams(preGrams);
				material.setRollDirect(preRoll);
				material.setIsPrint(prePrint);
				material.setGluePosition(preGlue);
				material.setKnifeNum(preKnife);
			}
			
			material.setSquare(square);
			if("平方".equals(unit.getName())) {
				material.setAmount(square);
			} else {
				material.setAmount(amount);
			}
//			if("吨".equals(unit.getName())) {
//				material.setAmount(tonAmount);
//			}
			String model = width.toString() + "*" + length.toString();
			material.setModel(model);
			saveList.add(material);
		}
		if(saveList.size() == 0) {
			return Result.error("维护失败。");
		}
		boolean isSuccess = this.materialTempService.saveBatch(saveList);
		if(!isSuccess) {
			return Result.error("维护失败。");
		}
		List<Map<String, String>> resultList = Lists.newLinkedList();
		Iterator<BasMaterialTemp> iterator = saveList.iterator();
		String dateStr = DateUtils.formatDate();
		while(iterator.hasNext()) {
			BasMaterialTemp temp  = iterator.next();
			//如果成功，将物料信息传回pda设备用于打印标签
			String numberStr = null;
			if(null == unit) {
				unit = unitService.getSquareUnit();
			}
			if("平方".equals(unit.getName())) {
				BigDecimal square = temp.getSquare();
				numberStr = square.toString();
			} else {
				numberStr = scanIo.getNumber();
			}
			String unitName = "";
			if (null != unit) {
				unitName = unit.getName();
			}
			String paperNum = "";
			if(qzFlag) {
				paperNum = scanIo.getNumber();
			}
			
			pids = temp.getPid();
			Map<String, String> resultMap = Maps.newHashMap();
			String preMaterial = "";
			if(formula != null) {
				preMaterial = formula.getPfName();
			}
			
			resultMap.put("preMaterial", preMaterial.trim());
			if(fhFlag) {
				dateStr = ScanUtil.changeDateToString(new Date()) + "A";
				resultMap.put("glue", temp.getGluePosition());
			}
			if(fqFlag) {
				dateStr = ScanUtil.changeDateToString(new Date()) + "B";
				String pid = temp.getPid();
				String[] strs = StringUtils.split(pid, ",");
				if(strs.length > 0) {
					pid = strs[0];
				}
				BasMaterial material = this.materialService.getById(pid);
				String code = material.getCode();
				if(null != material) {
					Date preTime = material.getCreateTime();
					String preTimeString = ScanUtil.changeDateToString(preTime) + "A";
					resultMap.put("fhTime", preTimeString);
				}
				
//				resultMap.put("preCode", code);
				BasMaterialTemp materialTemp = this.materialTempService.getByCode(code);
				String roll = scanIo.getRoll();
				if(roll == null) {
					roll = StringUtils.EMPTY;
				}
				resultMap.put("roll", roll);
				resultMap.put("glue", materialTemp.getGluePosition());
				Integer knifeNum = temp.getKnifeNum();
				resultMap.put("knife", null == knifeNum ? StringUtils.EMPTY : knifeNum.toString());	
				String machineId = materialTemp.getMachine();
				if(StringUtils.isNotBlank(machineId)) {
					ZzDevice zzDevice = this.deviceService.getById(machineId);
					if(zzDevice != null) {
						resultMap.put("preMachine", zzDevice.getDeviceName());
					}
				}
				resultMap.put("isPrint", materialTemp.getIsPrint());
				
			}
			if(qzFlag) {
				dateStr = ScanUtil.changeDateToString(new Date()) + "C";
				String pid = temp.getPid();
				String[] strs = StringUtils.split(pid, ",");
				if(strs.length > 0) {
					pid = strs[0];
				}
				BasMaterial fqMaterial = this.materialService.getById(pid);
				if(null != fqMaterial) {
					Date preTime = fqMaterial.getCreateTime();
					String preTimeString = ScanUtil.changeDateToString(preTime) + "B";
					resultMap.put("fqTime", preTimeString);
					String code = fqMaterial.getCode();
					BasMaterialTemp preTemp = this.materialTempService.getByCode(code);
					String prePid = preTemp.getPid();
					if(StringUtils.isNotBlank(prePid)) {
						String[] preStrs = StringUtils.split(prePid, ",");
						if(preStrs.length > 0) {
							prePid = preStrs[0];
						}
					}
					BasMaterial fhMaterial = this.materialService.getById(prePid);
					if(fhMaterial != null) {
						Date fhTime = fhMaterial.getCreateTime();
						String fhTimeStr = ScanUtil.changeDateToString(fhTime) + "A";
						resultMap.put("fhTime", fhTimeStr);
					}
				}
//				resultMap.put("preCode", code);
				Integer knifeNum = temp.getKnifeNum();
				resultMap.put("knife", null == knifeNum ? StringUtils.EMPTY : knifeNum.toString());
				
				resultMap.put("fqRoll", null == qzMap.get("fqRoll") ? StringUtils.EMPTY : qzMap.get("fqRoll"));
				resultMap.put("fqKnife", null == qzMap.get("fqKnife") ? StringUtils.EMPTY : qzMap.get("fqKnife"));
				resultMap.put("fqIn", null == qzMap.get("fqIn") ? StringUtils.EMPTY : qzMap.get("fqIn"));
				resultMap.put("fhRoll", null == qzMap.get("fhRoll") ? StringUtils.EMPTY : qzMap.get("fhRoll"));
			}
			resultMap.put("name", printName);
			resultMap.put("code", temp.getCode());
			resultMap.put("model", temp.getModel());
			resultMap.put("unit", unitName);
			resultMap.put("number", numberStr);
			resultMap.put("workNo", workNo);
			resultMap.put("paperNum", paperNum);
			resultMap.put("date", dateStr);
			resultMap.put("machine", mathineName);
			resultMap.put("remark", temp.getRemark());
			//传入客户
			BasCustomer customer = this.customerService.getById(customerId);
			if(null != customer) {
				String customerName = customer.getName();
				customerName = StringUtils.replace(customerName, "\n", "");
				customerName = StringUtils.replace(customerName, "\r", "");
				resultMap.put("customer", customerName);
//				if(!"1318447754322341890".equals(customer.getId())){
//					resultMap.put("preMaterial", "");
//				}
			} else {
				resultMap.put("customer", StringUtils.EMPTY);
			}
			
			resultList.add(resultMap);
		}

		return Result.ok(resultList);
	}

	@Override
	public void changePickUpEntryIsOut(String materialId, String procedureId) {
		if(StringUtils.isBlank(materialId)) {
			return;
		}
		StkPickUpBill pickUpBill = pickUpBillService.selectByProcessId(procedureId);
		if(null == pickUpBill) {
			return;
		}
		List<StkPickUpEntry> list = pickUpEntryService.selectByMainId(pickUpBill.getId());
		if(null == list || 0 == list.size()) {
			return;
		}
		BasMaterial material = materialService.getById(materialId);
		for (StkPickUpEntry stkPickUpEntry : list) {
			if(material.getCategoryId().equals(stkPickUpEntry.getMaterialId())) {
				stkPickUpEntry.setIsOut("1");
				pickUpEntryService.updateById(stkPickUpEntry);
				break;
			}
		}
		LambdaQueryWrapper<StkPickUpEntry> query = new LambdaQueryWrapper<>();
		query.eq(StkPickUpEntry::getBillId, pickUpBill.getId());
		query.eq(StkPickUpEntry::getIsOut, "0");
		int count = this.pickUpEntryService.count(query);
		if(0 == count) {
			pickUpBill.setBillStatus("2");
		} else {
			pickUpBill.setBillStatus("1");
		}
		this.pickUpBillService.updateById(pickUpBill);
	}

	@Override
	public String checkSaleOutOrder(ZrkShoporder order, List<BasMaterial> materialList, ScanIO scanIo) {
		//判断出库物料与订单中的物料是否相同
		List<ZrkOrderProduct> productList = orderProductService.selectByMainId(order.getId());
		if(CollUtil.isEmpty(productList)) {
			return "noproduct";
		}
		List<String> categoryIds = Lists.newArrayList();
		for(Iterator<ZrkOrderProduct> iterator = productList.iterator(); iterator.hasNext();) {
			ZrkOrderProduct product = iterator.next();
			categoryIds.add(product.getMaterialId());
			List<BasMaterialCategory> childrenList = basMaterialCategoryMapper.getAllChildCategoryHasChild(product.getMaterialId());
			if(childrenList != null && childrenList.size() > 0){
				for(BasMaterialCategory basMaterialCategory:childrenList){
					categoryIds.add(basMaterialCategory.getId());
				}
			}
		}
		for(Iterator<BasMaterial> iterator = materialList.iterator(); iterator.hasNext();) {
			BasMaterial material = iterator.next();
			String categoryId = material.getCategoryId();
			if(!categoryIds.contains(categoryId)) {
				return "noproduct";
			}
		}
		
		//将订单的产品需求总量进行汇总，并封装到一个map中
		Map<String, List<ShopOrderToCheck>> totalMap = Maps.newLinkedHashMap();
		for (ZrkOrderProduct product : productList) {
			String materialId = product.getMaterialId();
			if(null == materialId) {
				continue;
			}
			BasMaterialCategory category = this.categoryService.getById(materialId);
			if(null == category) {
				continue;
			}
			String unitId = product.getUnitId();
			if(StringUtils.isBlank(unitId)) {
				unitId = category.getUnitId();
				if(StringUtils.isBlank(unitId)) {
					unitId = category.getUnitId();
				}
			}
			List<ShopOrderToCheck> list2 = totalMap.get(category.getId());
			if(null == list2) {
				List<ShopOrderToCheck> list = Lists.newArrayList();
				ShopOrderToCheck check = new ShopOrderToCheck();
				
				check.setUnitId(unitId);
				check.setCategoryId(category.getId());
				check.setAmount(product.getProductCount());
				list.add(check);
				totalMap.put(category.getId(), list);
			} else {
				for(ShopOrderToCheck check : list2) {
					if(check.getUnitId().equals(unitId)) {
						BigDecimal num = product.getProductCount();
						num = num.add(check.getAmount());
						check.setAmount(num);
					} else {
						ShopOrderToCheck newCheck = new ShopOrderToCheck();
						newCheck.setUnitId(unitId);
						newCheck.setCategoryId(category.getId());
						newCheck.setAmount(product.getProductCount());
						list2.add(check);
					}
				}
			}
		}
		//取出所有的销售出货单，并进行封装
		List<ShopOrderToCheck> checkList = Lists.newArrayList();
		List<StkIoBill> bills = this.billService.getSaleOutBillBySourceCode(order.getOrderCode());
		if(null != bills && 0 != bills.size()) {
			for (StkIoBill stkIoBill : bills) {
				List<StkIoBillEntry> entrys = this.billEntryService.selectByMainId(stkIoBill.getId());
				for (StkIoBillEntry entry : entrys) {
					String materialId = entry.getMaterialId();
					BasMaterial material = this.materialService.getById(materialId);
					String unitId = entry.getUnitId();
					Iterator<ShopOrderToCheck> it = checkList.iterator();
					boolean flag = true;
					while(it.hasNext()) {
						ShopOrderToCheck tocheck = it.next();
						if(tocheck.getCategoryId().equals(material.getCategoryId())
								&& tocheck.getUnitId().equals(unitId)){
							BigDecimal amount = tocheck.getAmount();
							amount = amount.add(entry.getQty());
							tocheck.setAmount(amount);
							flag = false;
							break;
						}
					}
					if(flag) {
						ShopOrderToCheck tocheck = new ShopOrderToCheck();
						tocheck.setAmount(entry.getQty());
						tocheck.setCategoryId(material.getCategoryId());
						tocheck.setUnitId(unitId);
						checkList.add(tocheck);
					}
				}
			}
		}
		//计算传入的物料数量。
		Iterator<BasMaterial> iterator = materialList.iterator();
		while(iterator.hasNext()) {
			BasMaterial material = iterator.next();
			//获得该物料最近的入库记录
			List<StkIoBillEntry> perEntryList = billEntryService.selectByMaterial(material.getId());
			if(null == perEntryList || perEntryList.size() == 0) {
				return "noin";
			}
			StkIoBillEntry lastEntry = null;
			for (StkIoBillEntry stkIoBillEntry : perEntryList) {
				StkIoBill mBill = this.billService.getById(stkIoBillEntry.getMid());
				if(inTypes.contains(mBill.getStockIoType())) {
					lastEntry = stkIoBillEntry;
					break;
				}
			}
			if(lastEntry == null) {
				return "noin";
			}
			boolean flag = true;
			for (ShopOrderToCheck tockek : checkList) {
				if(tockek.getCategoryId().equals(material.getCategoryId()) && 
						tockek.getUnitId().equals(material.getUnitId())) {
					flag = false;
					BigDecimal amount = tockek.getAmount();
					amount = amount.add(lastEntry.getQty());
					tockek.setAmount(amount);
				}
			}
			if(flag) {
				ShopOrderToCheck tocke = new ShopOrderToCheck();
				tocke.setAmount(lastEntry.getQty());
				tocke.setUnitId(material.getUnitId());
				tocke.setCategoryId(material.getCategoryId());
				checkList.add(tocke);
			}
		}
		//根据物料的出入库情况检查物料数量是否正确。
		String isFinal = scanIo.getIsFinal();
		//判断误差值暂定为0.01
		BigDecimal onePercent = new BigDecimal("0.01");
		for (ShopOrderToCheck toCheck : checkList) {
			List<ShopOrderToCheck> list = totalMap.get(toCheck.getCategoryId());
			if(list == null) {
				continue;
			}
			for (ShopOrderToCheck shopOrderToCheck : list) {
				String unitId = shopOrderToCheck.getUnitId();
				if(unitId.equals(toCheck.getUnitId())) {
					//先判断别多了。
					if(toCheck.getAmount().compareTo(shopOrderToCheck.getAmount().multiply(BigDecimal.ONE.add(onePercent))) > 0) {
						//TODO
						return "1111more";
					}
					
					if("1".equals(isFinal)) {//如果是最终，除了判断是否别多了，还要判断别少了。
						if(toCheck.getAmount().compareTo(shopOrderToCheck.getAmount().multiply(BigDecimal.ONE.subtract(onePercent))) < 0) {
							return "1111less";
						}
					}	
				}
			}
		}
		
		return StringUtils.EMPTY;
	}

	@Override
	public Result<?> getMaterialWarehouse(ScanIO scanIo) {
		String code = scanIo.getCode();
		if(StringUtils.isBlank(code)) {
			return Result.error("物料编码不正确。");
		}
		//判断扫码的物料是不是托盘
		Boolean isTray = ScanUtil.isTrayCode(code);
		if(isTray) {
			StkTray tray = this.trayService.lambdaQuery().eq(StkTray::getCode, code).one();
			if(tray == null) {
				return Result.error("未找到编码对应的托盘。");
			}
			List<StkTrayDetail> detailList = this.trayDetailService.selectByMainId(tray.getId());
			if(CollUtil.isEmpty(detailList)) {
				return Result.error("该托盘上没有物料。");
			}
			List<String> materialIds = Lists.newArrayList();
			for(StkTrayDetail detail : detailList) {
				materialIds.add(detail.getMaterialId());
			}
			List<StkInventory> inventorys = this.inventoryService.lambdaQuery().in(StkInventory::getMaterialId, materialIds).list();
			if(CollUtil.isEmpty(inventorys)) {
				return Result.error("该托盘上的物料没有库存记录");
			}
			List<String> inventoryMaterialIds = Lists.newArrayList();
			List<String> warehourseIds = Lists.newArrayList();
			for(StkInventory inventory : inventorys) {
				String materialId = inventory.getMaterialId();
				if(!inventoryMaterialIds.contains(materialId)) {
					inventoryMaterialIds.add(materialId);
				}
				BigDecimal qty = inventory.getQty();
				if(qty != null && qty.compareTo(BigDecimal.ZERO) > 0 && !warehourseIds.contains(inventory.getWarehouseId())) {
					warehourseIds.add(inventory.getWarehouseId());
				}
			}
			List<String> outMaterialIds = Lists.newArrayList();
			for(String mateiralId : materialIds) {
				if(!inventoryMaterialIds.contains(mateiralId)) {
					outMaterialIds.add(mateiralId);
				}
			}
			if(CollUtil.isNotEmpty(outMaterialIds)) {
				List<String> codes = Lists.newArrayList();
				List<BasMaterial> materials = this.materialService.lambdaQuery().in(BasMaterial::getId, outMaterialIds).list();
				for (BasMaterial material : materials) {
					codes.add(material.getCode());
				}
				return Result.error("物料编码为" + CollUtil.join(codes, ",") + "的物料没有库存记录。");
			}
			if(1 < warehourseIds.size()) {
				return Result.error("托盘中的物料在不同的仓库，请分别扫码移库。");
			} else {
				Map<String, String> result = Maps.newHashMap();
				result.put("resultType", "ok");
				result.put("warehouseId", warehourseIds.get(0));
				result.put("code", tray.getCode());
				return Result.ok(result);
			}
		} else {
			BasMaterial material = this.materialService.getMaterialByCode(code);
			if(null == material) {
				return Result.error("未找到编码对应的物料。");
			}
			StkInventory inventory = inventoryService.getByMaterial(material.getId());
			String warehouseId = null != inventory ? inventory.getWarehouseId() : StringUtils.EMPTY;
			Map<String, String> result = Maps.newHashMap();
			result.put("resultType", "ok");
			result.put("warehouseId", warehouseId);
			result.put("code", material.getCode());
			return Result.ok(result);
		}
	}

	@Override
	@Transactional
	public Result<?> transfer(ScanIO scanIo) {
		// TODO Auto-generated method stub
		//检测传入的数据是否正确
		log.info("进入执行库存调拨");
		String warehouseId = scanIo.getWarehouseId();
		if(StringUtils.isBlank(warehouseId)) {
			return Result.error("请选择仓库。");
		}
		String list = scanIo.getList();
		JSONArray jsonArray = JSONObject.parseArray(list);
		if(jsonArray == null || jsonArray.size() == 0) {
			return Result.error("未传入物料编码。");
		}
		List<String> codeList = Lists.newArrayList();
		for(int i = 0; i < jsonArray.size(); i++) {
			JSONObject jsonObject = jsonArray.getJSONObject(i);
			String code = jsonObject.getString("code");
			codeList.add(code);
		}
		List<BasMaterial> materialList = Lists.newArrayList();
		List<String> materialCodes = Lists.newArrayList();
		for(Iterator<String> iterator = codeList.iterator(); iterator.hasNext();) {
			String code = iterator.next();
			Boolean isTray = ScanUtil.isTrayCode(code);
			if(isTray) {
				StkTray tray = this.trayService.lambdaQuery().eq(StkTray::getCode, code).one();
				if(tray != null) {
					List<StkTrayDetail> details = this.trayDetailService.selectByMainId(tray.getId());
					if(CollUtil.isEmpty(details)) {
						continue;
					}
					List<String> ids = Lists.newArrayList();
					for(Iterator<StkTrayDetail> it = details.iterator(); it.hasNext();) {
						StkTrayDetail detail = it.next();
						ids.add(detail.getMaterialId());
					}
					if(CollUtil.isNotEmpty(ids)) {
						List<BasMaterial> mList = this.materialService.lambdaQuery().in(BasMaterial::getId, ids).list();
						if(CollUtil.isNotEmpty(mList)) {
							materialList.addAll(mList);
						}
					}
				}
			} else {
				materialCodes.add(code);
			}
		}
		if(CollUtil.isNotEmpty(materialCodes)) {
			List<BasMaterial> materials = materialService.getByCodes(materialCodes);
			materialList.addAll(materials);
		}
		if(CollUtil.isEmpty(materialList)) {
			return Result.error("根据传入的编码，未查询相关物料。");
		}
		String userName = scanIo.getUserName();
		String orgCode = scanIo.getOrgCode();
		Date date = DateUtils.getDate();
		//封装库存调拨消息
		String billNo = basApi.getNoByCode("stock_io_bill_no");
		StkIoBill bill = new StkIoBill();
		bill.setStockIoType("301");
		bill.setBillDate(date);
		bill.setCreateBy(userName);
		bill.setCreateTime(date);
		bill.setBillNo(billNo);
		bill.setBillProcStatus(BILL_SUBMIT_STATUS);
		bill.setHandlerId(userName);
		bill.setHasRp(0);
		bill.setIsRubric(0);
		bill.setIsSameSettle(0);
		bill.setSysOrgCode(orgCode);
		List<StkIoBillEntry> entrys = Lists.newLinkedList();
		int entryNo = 10;
		Iterator<BasMaterial> iterator = materialList.iterator();
		while(iterator.hasNext()) {
			BasMaterial material = iterator.next();
			String materialId = material.getId();
			StkInventory inventory = inventoryService.getByMaterial(materialId);
			if(inventory == null) {
				continue;
			}
			StkIoBillEntry entry = new StkIoBillEntry();
			entry.setInWarehouseId(warehouseId);
			entry.setMaterialId(materialId);
			entry.setUnitId(material.getUnitId());
			entry.setInventoryUnitId(material.getUnitId());
			entry.setBatchNo(inventory.getBatchNo());
			entry.setEntryNo(entryNo);
			entry.setBillNo(billNo);
			entry.setInventoryCost(inventory.getCost());
			entry.setInventoryQty(inventory.getQty());
			entry.setQty(inventory.getQty());
			entry.setCost(inventory.getCost());
			entry.setWarehouseId(inventory.getWarehouseId());
			entry.setSupplierId(inventory.getSupplierId());
			entrys.add(entry);
			entryNo = entryNo + 10;
		}
		if(entrys.size() == 0) {
			return Result.error("物料编码与实时库存不匹配。");
		}
		billService.saveMain(bill, entrys);
		billService.approve(bill.getId());
		log.info("库存调拨完成" + bill.getBillNo());
		return Result.ok();
	}

	@Override
	public Result<JSONObject> tempStorage(ScanIO scanIo, Result<JSONObject> result) {
		// TODO Auto-generated method stub
		StkIoBill bill = this.billService.getByCode("STK-20201120-000004");
		List<StkIoBillEntry> entrys = this.billEntryService.selectByMainId(bill.getId());
		if(null == entrys) {
			entrys = Lists.newArrayList();
		}
		BasMaterial material = scanService.getMaterialByCode(scanIo.getCode());
		Date date = DateUtils.getDate();
		String unitId = scanIo.getUnit();
		BasMeasureUnit unit = this.unitService.getById(unitId);//单位
		BigDecimal checkNumber = new BigDecimal(scanIo.getNumber());//获取物料数量
		int maxBatchNo = 0;
		int maxEntryNo = 0;
//		BigDecimal settlePrice = cost.divide(checkNumber, 2, BigDecimal.ROUND_DOWN);
		BigDecimal settlePrice = scanIo.getAmount();//临时录入时是单价
		if(null == settlePrice) {
			result.setSuccess(false);
			result.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
			result.setMessage("请填写价格。");
			return result;
		}
//		BigDecimal cost = scanIo.getAmount();//取出成本
		BigDecimal cost = settlePrice.multiply(checkNumber);
		cost = cost.setScale(2, BigDecimal.ROUND_HALF_UP);
		for (StkIoBillEntry stkIoBillEntry2 : entrys) {
			String batchNo = stkIoBillEntry2.getBatchNo();
			String[] nos = batchNo.split("-");
			String no = nos[nos.length-1];
			int num = 0;
			try {
				num = Integer.parseInt(no);
			} catch (Exception e) {
			}
			if(num > maxBatchNo) {
				maxBatchNo = num;
			}
			if(stkIoBillEntry2.getEntryNo() > maxEntryNo) {
				maxEntryNo = stkIoBillEntry2.getEntryNo();
			}
		}
		if(StringUtils.isNotBlank(scanIo.getModel())) {
			material.setModel(scanIo.getModel());
		}
		material.setSalePrice(null);
		BigDecimal length = scanIo.getLength();
		if(null != length) {
			material.setLength(length);
		}
		BigDecimal width = scanIo.getWidth();
		if(null != width) {
			material.setWidth(width);
		}
		//吨转平方
		if("吨".equals(unit.getName())) {
			BigDecimal square = this.categoryService.getSquare(checkNumber, material.getCategoryId());
			material.setSquare(square);
		}if("平方".equals(unit.getName())) {
			material.setSquare(checkNumber);
		}
		this.materialService.updateById(material);
		StkIoBillEntry billEntry = new StkIoBillEntry();
		billEntry.setMaterialId(material.getId());
		billEntry.setBillNo(bill.getBillNo());
		billEntry.setMid(bill.getId());
		maxBatchNo = maxBatchNo + 10;
		billEntry.setBatchNo(bill.getBillNo() + "-" + maxBatchNo);
		billEntry.setQty(checkNumber);
		billEntry.setSourceType(bill.getSourceType());
		if(null != width) {
			billEntry.setWidth(width);
		}
		billEntry.setSettlePrice(settlePrice);
		billEntry.setLength(length);
		billEntry.setUnitId(material.getUnitId());
		billEntry.setWarehouseId(scanIo.getWarehouseId());
		billEntry.setSettleQty(checkNumber);
		billEntry.setEntryNo(maxEntryNo + 1);
		billEntry.setCost(cost);
		billEntry.setSettleAmt(cost);
		billEntry.setSettleQty(checkNumber);
		billEntry.setSupplierId(bill.getSupplierId());
//		billEntry.setSettlePrice(materialPrice);
//		entrys.add(billEntry);
		
		stkIoBillEntryMapper.insert(billEntry);
//		this.billService.updateMain(bill, entrys);
		this.inventoryService.increase(billEntry);//入库完成添加实时库存
		logService.insertLog(bill.getId(), date, billEntry.getId(), bill.getStockIoType(), 0, material, unit.getId(), "into101", 1, cost, billEntry.getQty(), scanIo.getProcedureId());
		result.setSuccess(true);
		result.setCode(CommonConstant.SC_OK_200);
		result.setMessage("采购入库完成");
		return result;
	}

	@Override
	public BigDecimal computingStorageCosts(StkIoBill purchaseOrder, BasMaterial material, BigDecimal number) {
		// TODO Auto-generated method stub
		//取出采购单的明细
		List<StkIoBillEntry> purchaseEntrys = this.billEntryService.selectByMainId(purchaseOrder.getId());
		if(null == purchaseEntrys || 0 == purchaseEntrys.size()) {
			return BigDecimal.ZERO;
		}
		//取出与当前物料的物料分类相同的明细
		List<StkIoBillEntry> costPurchaseEntrys = Lists.newLinkedList();
		Iterator<StkIoBillEntry> iterator = purchaseEntrys.iterator();
		while(iterator.hasNext()) {
			StkIoBillEntry entry = iterator.next();
			if(entry.getMaterialId().equals(material.getCategoryId())) {
				costPurchaseEntrys.add(entry);
			}
		}
		if(null == costPurchaseEntrys || 0 == costPurchaseEntrys.size()) {
			return BigDecimal.ZERO;
		}
		//计算物料的总成本
		BigDecimal totalCost = BigDecimal.ZERO;
		Iterator<StkIoBillEntry> costIt = costPurchaseEntrys.iterator();
		while(costIt.hasNext()) {
			StkIoBillEntry costEn = costIt.next();
			BigDecimal stoCost = costEn.getCost();
			totalCost = totalCost.add(stoCost);
		}
		//通过采购单获得与本采购单相符的采购入库明细
		String orderNo = purchaseOrder.getBillNo();
		
		
		//取出与当前物料相同的已入库的物料，按照入库数量摊分成本
		//如果传入的list为空，则返回总成本。
		List<StkIoBillEntry> list = this.billEntryService.selectByPurchase(orderNo);
		if(null == list || 0 == list.size()) {
			return totalCost;
		}
		Iterator<StkIoBillEntry> allIt = list.iterator();
		List<String> materialIds = Lists.newArrayList();
		while (allIt.hasNext()) {
			StkIoBillEntry entry = allIt.next();
			materialIds.add(entry.getMaterialId());
		}
		List<BasMaterial> materials = this.materialService.getByIds(materialIds);
		//取出与当前物料分类相同的物料的ID
		List<String> materialIdComputList = Lists.newArrayList();
		for (BasMaterial basMaterial : materials) {
			if(basMaterial.getCategoryId().equals(material.getCategoryId())) {
				materialIdComputList.add(basMaterial.getId());
			}
		}
		if(0 == materialIdComputList.size()) {
			return totalCost;
		}
		List<StkIoBillEntry> computList = Lists.newLinkedList();
		for (StkIoBillEntry stkIoBillEntry : list) {
			if(materialIdComputList.contains(stkIoBillEntry.getMaterialId())) {
				computList.add(stkIoBillEntry);
			}
		}
		if(0 == computList.size()) {
			return totalCost;
		}
		//计算总数量
		BigDecimal totalNum = BigDecimal.ZERO;
		List<String> entryIds = Lists.newArrayList();
		for (StkIoBillEntry stkIoBillEntry : computList) {
			totalNum = totalNum.add(stkIoBillEntry.getQty());
			entryIds.add(stkIoBillEntry.getId());
		}
		List<StkIoMaterialLog> logList = this.logService.selectByEntryIds(entryIds);
		Map<String, StkIoMaterialLog> logMap = Maps.newHashMap();
		for (StkIoMaterialLog stkIoMaterialLog : logList) {
			logMap.put(stkIoMaterialLog.getEntityId(), stkIoMaterialLog);
		}
		totalNum = totalNum.add(number);
		//根据所占比例计算各个物料的成本
		BigDecimal restCost = BigDecimal.ZERO;
		for (StkIoBillEntry entry : computList) {
			BigDecimal qty = entry.getQty();
			BigDecimal newCost = qty.divide(totalNum, 2, BigDecimal.ROUND_DOWN).multiply(totalCost);
			restCost = restCost.add(newCost);
			//更新入库成本
			entry.setCost(newCost);
			entry.setSettleAmt(newCost);
			this.billEntryService.updateById(entry);
			//更新实时库存成本
			this.inventoryService.updateProductInCost(entry);
			//更新日志记载的成本
			StkIoMaterialLog log = logMap.get(entry.getId());
			if(null != log) {
				log.setCost(newCost);
				this.logService.updateById(log);
			}
		}
		BigDecimal cost = totalCost.subtract(restCost);
		return cost;
	}

	//胶水入库
	@Override
	public Result<JSONObject> glueIn(ScanIO scanIo, Result<JSONObject> result) {
		// TODO Auto-generated method stub
		String listStr = scanIo.getList();
		if(StringUtils.isBlank(listStr)) {
			return result.error500("请扫描物料编码。");
		}
		JSONArray jsonArray = JSON.parseArray(listStr);
		if(jsonArray.size() == 0) {
			return result.error500("请扫描物料编码。");
		}
		String warehouseId = scanIo.getWarehouseId();
		if(StringUtils.isBlank(warehouseId)) {
			return result.error500("请选择仓库。");
		}
		List<BasMaterial> materials = Lists.newArrayList();
		for (int i = 0; i < jsonArray.size(); i++) {
			JSONObject jsonObject = jsonArray.getJSONObject(i);
			String code = jsonObject.getString("code");
			if(StringUtils.isNotBlank(code)) {
				BasMaterial material = scanService.getMaterialByCode(code);
				if(null != material) {
					materials.add(material);
				} else {
					return result.error500("未找到编码" + code + "对应的物料");
				}
			}
		}
		if(CollUtil.isEmpty(materials)) {
			return result.error500("未找到编码对应的物料");
		}
		//判断是否重复出库
		String operType = scanIo.getOperType();
		boolean inFlag = false;
		boolean outFlag = false;
		for (String string : ScanServiceImpl.inTypes) {
			if (operType.equals(string)) {
				inFlag = true;
				break;
			}
		}
		for (String string : ScanServiceImpl.outTypes) {
			if (operType.equals(string)) {
				outFlag = true;
				break;
			}
		}
		
		
		Map<String, List<BasMaterial>> materialMap = Maps.newHashMap();
		Map<String, BasMaterialTemp> tempMap = Maps.newHashMap();
		Map<String, BasMaterial> materialIdMap = Maps.newHashMap();
		for (Iterator<BasMaterial> it = materials.iterator(); it.hasNext();) {
			BasMaterial material = it.next();
			String code = material.getCode();
			
			StkIoBill latestBill = this.billMapper.selectByMaterialCode(code);
			if (null != latestBill) {
				String type = latestBill.getStockIoType();
				if (operType.equals(type)) {
					return result.error500(new StringBuffer("编码为").append(code).append("的物料已入库，不能重复操作").toString());
				}
				boolean inF = false;
				boolean outF = false;
				for (String string : ScanServiceImpl.inTypes) {
					if (type.equals(string)) {
						inF = true;
						break;
					}
				}
				for (String string : ScanServiceImpl.outTypes) {
					if (type.equals(string)) {
						outF = true;
						break;
					}
				}
				if ((inFlag && inF) || (outFlag && outF)) {
					return result.error500(new StringBuffer("编码为").append(code).append("的物料已入库，不能重复操作").toString());
				}
			}
			
			BasMaterialTemp temp = this.materialTempService.getByCode(code);
			String mesId = temp.getProcedureId();
			tempMap.put(code, temp);
			List<BasMaterial> list = materialMap.get(mesId);
			if(null == list) {
				list = Lists.newArrayList();
				list.add(material);
				materialMap.put(mesId, list);
			} else {
				list.add(material);
			}
			materialIdMap.put(material.getId(), material);
		}
		Date date = DateUtil.date();
		Map<StkIoBill, List<StkIoBillEntry>> billMap = Maps.newHashMap();
		for (String mesId : materialMap.keySet()) {
			ZrkQzOrder mes = this.mesService.getById(mesId);
			List<BasMaterial> list = materialMap.get(mesId);
			
			String billNo = basApi.getNoByCode("stock_io_bill_no");
			String stockIoType = scanIo.getOperType();
			String userName = scanIo.getUserName();
			StkIoBill bill = new StkIoBill();
			bill.setBillNo(billNo);
			bill.setStockIoType(stockIoType);
			bill.setBillDate(date);
			bill.setIsAuto(1);
			bill.setClerkId(userName);
			bill.setHandlerId(userName);
			bill.setIsApproved(1);//是否通过 审批
			bill.setCreateBy(userName);
			bill.setCreateTime(date);
			bill.setIsRubric(0);
			bill.setHasRp(1);
			bill.setSourceId(mes.getId());
			bill.setSourceNo(mes.getCode());
			bill.setSourceType(ScanServiceImpl.PRODUCTION_SOURCE_TYPE);
			bill.setBillProcStatus(BILL_STATUS_APPROVAL);
			bill.setSysOrgCode(scanIo.getOrgCode());
			bill.setIsPda(1);
			bill.setSupplierId(CommonConstant.QY_SUPPLIER_ID);
			
			List<StkIoBillEntry> entrys = Lists.newArrayList();
			int entryNo = 1;
			for (BasMaterial material : list) {
				StkIoBillEntry billEntry = new StkIoBillEntry();
				billEntry.setMaterialId(material.getId());
				billEntry.setBillNo(billNo);
				billEntry.setMid(bill.getId());
				int batchNo = entryNo * 10;
				billEntry.setBatchNo(billNo + "-" + batchNo);
				billEntry.setQty(material.getQuantity());
				billEntry.setSourceType(bill.getSourceType());
				billEntry.setUnitId(material.getUnitId());
				billEntry.setWarehouseId(scanIo.getWarehouseId());
				billEntry.setSettleQty(material.getQuantity());
				billEntry.setEntryNo(entryNo);
				BasMaterialTemp temp = tempMap.get(material.getCode());
				billEntry.setCost(temp.getCost());
				BigDecimal settlePrice = temp.getCost().divide(material.getQuantity(), 2, BigDecimal.ROUND_DOWN);
				billEntry.setSettlePrice(settlePrice);
				billEntry.setSettleAmt(temp.getCost());
				billEntry.setSettleQty(material.getQuantity());
				billEntry.setSupplierId(CommonConstant.QY_SUPPLIER_ID);
				entrys.add(billEntry);
				
				entryNo++;
			}
			billMap.put(bill, entrys);
		}
		
		for(StkIoBill bill : billMap.keySet()) {
			List<StkIoBillEntry> entryList = billMap.get(bill);
			this.billService.saveMain(bill, entryList);
			this.billService.updateInventory(bill, entryList);
			for (StkIoBillEntry billEntry : entryList) {
				BasMaterial material = materialIdMap.get(billEntry.getMaterialId());
				if(null == material) {
					material = this.materialService.getById(billEntry.getMaterialId());
				}
				logService.insertLog(bill.getId(), date, billEntry.getId(), scanIo.getOperType(), 0, material, scanIo.getUnit(), bill.getSourceId(), 1, billEntry.getCost(), billEntry.getQty(), bill.getSourceId());
			}
		}
		System.out.println("胶水入库完成");
		result.setSuccess(true);
		result.setCode(CommonConstant.SC_OK_200);
		result.setMessage("胶水入库完成");
		return result;
	}

	@Override
	public Result<JSONObject> existedHalfIn(ScanIO scanIo, Result<JSONObject> result) {
		// TODO Auto-generated method stub
		String warehouseId = scanIo.getWarehouseId();
		if(StringUtils.isBlank(warehouseId)) {
			return result.error500("请选择仓库。");
		}
		String unitId = scanIo.getUnit();
		if(StringUtils.isBlank(unitId)) {
			return result.error500("请选择单位。");
		}
		String code = scanIo.getCode();
		if(StringUtils.isBlank(code)) {
			return result.error500("请扫码。");
		}
		String numberStr = scanIo.getNumber();
		if(StringUtils.isBlank(numberStr)) {
			return result.error500("请输入数量。");
		}
		String userName = scanIo.getUserName();
		String orgCode = scanIo.getOrgCode();
		BigDecimal amount = scanIo.getAmount();
		if(null == amount) {
			return result.error500("请输入金额。");
		}
		BasMeasureUnit unit = this.unitService.getById(unitId);
		if(null == unit) {
			return result.error500("请选择单位。");
		}
		BasWarehouse warehouse = this.warehouseService.getById(warehouseId);
		if(null == warehouse) {
			return result.error500("请选择仓库。");
		}
		BigDecimal width = scanIo.getWidth();
		BigDecimal length = scanIo.getLength();
		BasMaterial material = scanService.getMaterialByCode(scanIo.getCode());
		BigDecimal number = new BigDecimal(numberStr);
		if(null == material) {
			return result.error500("未找到物料。");
		}
		//更新物料长宽等
		material.setLength(length);
		material.setWidth(width);
		material.setUnitId(unitId);
		if(unit.getName().equals("平方")) {
			material.setSquare(number);
		}
		this.materialService.updateById(material);
		Date date = DateUtils.getDate();
		
		//封装入库信息
		String billNo = basApi.getNoByCode("stock_io_bill_no");
		String stockIoType = scanIo.getOperType();
		StkIoBill bill = new StkIoBill();
		bill.setBillNo(billNo);
		bill.setStockIoType(stockIoType);
		bill.setBillDate(date);
		bill.setIsAuto(1);
		bill.setClerkId(userName);
		bill.setHandlerId(userName);
		bill.setIsApproved(0);//是否通过审批
		bill.setCreateBy(userName);
		bill.setCreateTime(date);
		bill.setIsRubric(0);
		bill.setHasRp(1);
		bill.setBillProcStatus(BILL_STATUS_APPROVAL);
		bill.setSysOrgCode(orgCode);
		bill.setIsPda(1);
		bill.setSupplierId(CommonConstant.QY_SUPPLIER_ID);
		
		StkIoBillEntry billEntry = new StkIoBillEntry();
		billEntry.setMaterialId(material.getId());
		billEntry.setBillNo(billNo);
		billEntry.setMid(bill.getId());
		billEntry.setBatchNo(billNo + "-10");
		billEntry.setQty(number);
		billEntry.setSourceType(bill.getSourceType());
		billEntry.setUnitId(material.getUnitId());
		billEntry.setWarehouseId(scanIo.getWarehouseId());
		billEntry.setSettleQty(number);
		billEntry.setEntryNo(1);
		billEntry.setCost(amount);
		billEntry.setWidth(width);
		billEntry.setLength(length);
		BigDecimal settlePrice = amount.divide(number, 2, BigDecimal.ROUND_DOWN);
		billEntry.setSettlePrice(settlePrice);
		billEntry.setSettleAmt(amount);
		billEntry.setSettleQty(number);
		billEntry.setSupplierId(CommonConstant.QY_SUPPLIER_ID);
		
		List<StkIoBillEntry> entryList = Lists.newLinkedList();
		entryList.add(billEntry);
		this.billService.saveMain(bill, entryList);
		this.billService.updateInventory(bill, entryList);
		
		System.out.println("已有半成品入库完成");
		result.setSuccess(true);
		result.setCode(CommonConstant.SC_OK_200);
		result.setMessage("已有半成品入库完成");
		return result;
	}

	@Override
	public Result<?> inspector() {
		List<ErpSysUser> list = this.scanMapper.getInspector();
		return Result.ok(list);
	}

	@Override
	public Result<?> trace(String code) {
		BasMaterial material = this.materialService.getMaterialByCode(code);
		if(null == material) {
			return Result.error("未找到物料信息");
		}
		String materialId = material.getId();
		List<StkIoMaterialLog> logList = this.logService.getByMaterial(materialId);
		List<String> resultList = Lists.newLinkedList();
		String nameStr = "物料名称：" + material.getName();
		String codeStr = "物料编号：" + material.getCode();
		resultList.add(nameStr);
		resultList.add(codeStr);
		if(logList != null && 0 != logList.size()) {
			Iterator<StkIoMaterialLog> iterator = logList.iterator();
			while(iterator.hasNext()) {
				StkIoMaterialLog materialLog = iterator.next();
				String billId = materialLog.getBillId();
				String entryId = materialLog.getEntityId();
				StkIoBill bill = billService.getById(billId);
				//判断出入库类型
				if(null == bill) {
					continue;
				}
				String ioType = bill.getStockIoType();
				Date time = bill.getCreateTime();
				String string = DateUtils.date2Str(time, DateUtils.date_sdf_wz.get());
				if(ioType.equals("201")) {
					string += "销售出库。";
					resultList.add(string);
					string = "出库单号为：" + bill.getBillNo();
					resultList.add(string);
					String customerId = bill.getCustomerId();
					BasCustomer customer = this.customerService.getById(customerId);
					if(null != customer) {
						resultList.add("客户为：" + customer.getName());
					}
				}
				if(ioType.equals("1991")) {
					string += "切张完成并入库。";
					resultList.add(string);
					String procedureId = materialLog.getProcedureId();
					String productOrderId = materialLog.getProductOrderId();
					ZzShoporder shoporder = shopOrderService.getById(productOrderId);
					if(null != shoporder) {
						resultList.add("生产订单流水号为：" + shoporder.getWoPartcode());
					}
					ZrkOrderProcess orderProcess = this.processService.getById(procedureId);
					if(null != orderProcess) {
						resultList.add("工序编号为：" + orderProcess.getProcessCode());
						String userIds = orderProcess.getUserId();
						if(StringUtils.isNotBlank(userIds)) {
							String[] userIdArray = StringUtils.split(userIds, ",");
							String userCodes = "";
							for (String userId : userIdArray) {
								List<ErpSysUser> userList = this.userMapper.getUser(userId);
								if(null != userList && userList.size() > 0) {
									ErpSysUser sysUser = userList.get(0);
									userCodes = userCodes + sysUser.getWorkNo() + ",";
								}
							}
							if(!"".equals(userCodes)) {
								userCodes = userCodes.substring(0, userCodes.length()-1);
								resultList.add("生产员工工号为：" + userCodes);
							}
						}
						String deviceId = orderProcess.getDeviceId();
						ZzDevice device = this.deviceService.getById(deviceId);
						if(null != device) {
							resultList.add("机器编号为：" + device.getDeviceName());
						}
					}
					String pid = material.getPid();
					if(StringUtils.isNotBlank(pid)) {
						String[] pids = StringUtils.split(pid, ",");
						String pidNameString = "";
						for (int i = 0; i < pids.length; i++) {
							String mId = pids[i];
							BasMaterial pmate = this.materialService.getById(mId);
							if(null != pmate) {
								pidNameString += pmate.getCode() + ",";
							}
						}
						if(!"".equals(pidNameString)) {
							pidNameString = pidNameString.substring(0, pidNameString.length()-1);
						}
						resultList.add("原物料编号为：" + pidNameString);
					}
				}
				if(ioType.equals("2993")) {
					string += "分切出库。";
					resultList.add(string);
					String procedureId = materialLog.getProcedureId();
					String productOrderId = materialLog.getProductOrderId();
					ZzShoporder shoporder = shopOrderService.getById(productOrderId);
					if(null != shoporder) {
						resultList.add("生产订单流水号为：" + shoporder.getWoPartcode());
					}
					ZrkOrderProcess orderProcess = this.processService.getById(procedureId);
					if(null != orderProcess) {
						resultList.add("工序编号为：" + orderProcess.getProcessCode());
					}
				}
				if(ioType.equals("1993")) {
					string += "分切完成并入库。";
					resultList.add(string);
					String procedureId = materialLog.getProcedureId();
					String productOrderId = materialLog.getProductOrderId();
					ZzShoporder shoporder = shopOrderService.getById(productOrderId);
					if(null != shoporder) {
						resultList.add("生产订单流水号为：" + shoporder.getWoPartcode());
					}
					ZrkOrderProcess orderProcess = this.processService.getById(procedureId);
					if(null != orderProcess) {
						resultList.add("工序编号为：" + orderProcess.getProcessCode());
						String userIds = orderProcess.getUserId();
						if(StringUtils.isNotBlank(userIds)) {
							String[] userIdArray = StringUtils.split(userIds, ",");
							String userCodes = "";
							for (String userId : userIdArray) {
								List<ErpSysUser> userList = this.userMapper.getUser(userId);
								if(null != userList && userList.size() > 0) {
									ErpSysUser sysUser = userList.get(0);
									userCodes = userCodes + sysUser.getWorkNo() + ",";
								}
							}
							if(!"".equals(userCodes)) {
								userCodes = userCodes.substring(0, userCodes.length()-1);
								resultList.add("生产员工工号为：" + userCodes);
							}
						}
						String deviceId = orderProcess.getDeviceId();
						ZzDevice device = this.deviceService.getById(deviceId);
						if(null != device) {
							resultList.add("机器编号为：" + device.getDeviceName());
						}
					}
					BasMaterialTemp temp = this.materialTempService.getByCode(codeStr);
					String layerStr = temp.getSurfaceLayer();
					if(StringUtils.isNotBlank(layerStr)) {
						resultList.add("面层：" + layerStr);
					}
					String pid = material.getPid();
					if(StringUtils.isNotBlank(pid)) {
						String[] pids = StringUtils.split(pid, ",");
						String pidNameString = "";
						for (int i = 0; i < pids.length; i++) {
							String mId = pids[i];
							BasMaterial pmate = this.materialService.getById(mId);
							if(null != pmate) {
								pidNameString += pmate.getCode() + ",";
							}
						}
						if(!"".equals(pidNameString)) {
							pidNameString = pidNameString.substring(0, pidNameString.length()-1);
						}
						resultList.add("原物料编号为：" + pidNameString);
					}
				}
				if(ioType.equals("2993")) {
					string += "分切出库。";
					resultList.add(string);
					String procedureId = materialLog.getProcedureId();
					String productOrderId = materialLog.getProductOrderId();
					ZzShoporder shoporder = shopOrderService.getById(productOrderId);
					if(null != shoporder) {
						resultList.add("生产订单流水号为：" + shoporder.getWoPartcode());
					}
					ZrkOrderProcess orderProcess = this.processService.getById(procedureId);
					if(null != orderProcess) {
						resultList.add("工序编号为：" + orderProcess.getProcessCode());
					}
				}
				if(ioType.equals("101")) {
					string += "采购入库。";
					resultList.add(string);
					StkIoBillEntry billEntry = this.billEntryService.getById(entryId);
					String supplierId = bill.getSupplierId();
					resultList.add("采购入库单码为：" + bill.getBillNo());
					if(StringUtils.isNotBlank(supplierId)) {
						BasSupplier supplier = this.supplierService.getById(supplierId);
						if(supplier != null) {
							resultList.add("供应商为：" + supplier.getName());
						}
					}
					if(null != billEntry) {
						
					}
				}
				
			}
		}
		
		String pid = material.getPid();
		if(StringUtils.isNotBlank(pid)) {
			
		}
		return Result.ok(resultList);
	}

	@Override
	public List<StkIoBillEntry> countCost(List<StkIoBillEntry> entryList, String operType, String mesId,
			List<BasMaterialTemp> tempList, Map<String, BasMaterial> materialMap,
			Map<String, BasMaterial> materialMapKeyId) {
		// TODO Auto-generated method stub
		Map<String, BasMaterialTemp> tempMap = Maps.newHashMap();
		for (BasMaterialTemp temp : tempList) {
			tempMap.put(temp.getCode(), temp);
		}
		if(null == entryList) {
			return entryList;
		}
		//切张
		if("1991".equals(operType)) {
			List<StkIoBill> list = this.billService.lambdaQuery().eq(StkIoBill::getSourceId, mesId).orderByAsc(StkIoBill::getCreateTime).list();
			BigDecimal totalCost = BigDecimal.ZERO;
			if(null == list) {
				return entryList;
			}
			for(Iterator<StkIoBillEntry> it = entryList.iterator(); it.hasNext(); ) {
				StkIoBillEntry billEntry = it.next();
				String materialId = billEntry.getMaterialId();
				BasMaterial basMaterial = materialMapKeyId.get(materialId);
				if(null == basMaterial) {
					this.materialService.getById(materialId);
				}
				String code = basMaterial.getCode();
				BasMaterialTemp materialTemp = tempMap.get(code);
				if(null == materialTemp) {
					materialTemp = this.materialTempService.getByCode(code);
				}
				if(null == materialTemp) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				String pid = materialTemp.getPid();
				if(StringUtils.isBlank(pid)) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				String[] pidArray = StrUtil.split(pid, ",");
				List<IoEntryDTO> dtoList = Lists.newArrayList();
				for(int i = 0; i < pidArray.length; i++) {
					List<IoEntryDTO> entryDtoList = this.scanMapper.getStkIoBillEntryByMesMaterial(pidArray[i], mesId);
					for (IoEntryDTO ioEntryDTO : entryDtoList) {
						String ioType = ioEntryDTO.getIoType();
						if(StrUtil.startWith(ioType, "2")) {
							dtoList.add(ioEntryDTO);
						}
					}
				}
				if(CollUtil.isEmpty(dtoList)) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				BigDecimal theCost = BigDecimal.ZERO;
				BigDecimal theQty = BigDecimal.ZERO;
				for(Iterator<IoEntryDTO> itera = dtoList.iterator(); itera.hasNext();) {
					IoEntryDTO dto = itera.next();
					BigDecimal cost = dto.getCost();
					BigDecimal qty = dto.getQty();
					if(null != cost) {
						theCost = theCost.add(cost);
					}
					if(null != qty) {
						theQty = theQty.add(qty);
					}
				}
				if(BigDecimal.ZERO.compareTo(theQty) >= 0 || BigDecimal.ZERO.compareTo(theCost) >= 0) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				BigDecimal qty = billEntry.getQty();
				BigDecimal cost = qty.multiply(theCost).divide(theQty, 2, BigDecimal.ROUND_DOWN);
				billEntry.setCost(cost);
			}
		}
		//复合
		if("1992".equals(operType)) {
			List<StkIoBill> list = this.billService.lambdaQuery().eq(StkIoBill::getSourceId, mesId).orderByAsc(StkIoBill::getCreateTime).list();
			BigDecimal totalCost = BigDecimal.ZERO;
			if(null == list) {
				return entryList;
			}
			BigDecimal inCost = BigDecimal.ZERO;
			BigDecimal outCost = BigDecimal.ZERO;
			List<StkIoBillEntry> entrys = Lists.newArrayList();
			for(Iterator<StkIoBill> iterator = list.iterator(); iterator.hasNext();) {
				StkIoBill bill = iterator.next();
				String ioType = bill.getStockIoType();
				List<StkIoBillEntry> ioBillEntrys = this.stkIoBillEntryMapper.selectByMainId(bill.getId());
				if(CollUtil.isEmpty(ioBillEntrys)) {
					if(ioType.equals("1994")) {
						for (StkIoBillEntry entry : ioBillEntrys) {
							BigDecimal cost = entry.getCost();
							if(null != cost) {
								inCost = inCost.add(cost);
							}
						}
					} else if(StringUtils.startsWith(ioType, "2")) {
						for (StkIoBillEntry entry : ioBillEntrys) {
							BigDecimal cost = entry.getCost();
							if(null != cost) {
								outCost = outCost.add(cost);
							}
						}
					} else if(StringUtils.startsWith(ioType, "1")) {
						for (StkIoBillEntry entry : ioBillEntrys) {
							entrys.add(entry);
						}
					}
				}	
			}
			totalCost = outCost.subtract(inCost);
			if(CollUtil.isEmpty(entrys)) {
				BigDecimal totalQty = BigDecimal.ZERO;
				for (Iterator<StkIoBillEntry> iterator = entryList.iterator(); iterator.hasNext();) {
					StkIoBillEntry entry = iterator.next();
					totalQty = totalQty.add(entry.getQty());
				}
				for (Iterator<StkIoBillEntry> iterator = entryList.iterator(); iterator.hasNext();) {
					StkIoBillEntry entry = iterator.next();
					BigDecimal qty = entry.getQty();
					BigDecimal cost = totalCost.multiply(qty).divide(totalQty, 2, BigDecimal.ROUND_DOWN);
					entry.setCost(cost);
				}
			} else {
				BigDecimal totalQty = BigDecimal.ZERO;
				for (Iterator<StkIoBillEntry> iterator = entryList.iterator(); iterator.hasNext();) {
					StkIoBillEntry entry = iterator.next();
					totalQty = totalQty.add(entry.getQty());
				}
				for (Iterator<StkIoBillEntry> iterator = entrys.iterator(); iterator.hasNext(); ) {
					StkIoBillEntry entry = iterator.next();
					totalQty = totalQty.add(entry.getQty());
				}
				for (Iterator<StkIoBillEntry> iterator = entryList.iterator(); iterator.hasNext();) {
					StkIoBillEntry entry = iterator.next();
					BigDecimal qty = entry.getQty();
					BigDecimal cost = totalCost.multiply(qty).divide(totalQty, 2, BigDecimal.ROUND_DOWN);
					entry.setCost(cost);
				}
				for (Iterator<StkIoBillEntry> iterator = entrys.iterator(); iterator.hasNext(); ) {
					StkIoBillEntry entry = iterator.next();
					BigDecimal qty = entry.getQty();
					BigDecimal cost = totalCost.multiply(qty).divide(totalQty, 2, BigDecimal.ROUND_DOWN);
					entry.setCost(cost);
				}
				this.billEntryService.updateBatchById(entrys);
			}
			
			
		}
		//分切
		if("1993".equals(operType)) {
			List<StkIoBill> list = this.billService.lambdaQuery().eq(StkIoBill::getSourceId, mesId).orderByAsc(StkIoBill::getCreateTime).list();
			if(null == list) {
				return entryList;
			}
			for(Iterator<StkIoBillEntry> it = entryList.iterator(); it.hasNext(); ) {
				StkIoBillEntry billEntry = it.next();
				String materialId = billEntry.getMaterialId();
				BasMaterial basMaterial = materialMapKeyId.get(materialId);
				if(null == basMaterial) {
					this.materialService.getById(materialId);
				}
				String code = basMaterial.getCode();
				BasMaterialTemp materialTemp = tempMap.get(code);
				if(null == materialTemp) {
					materialTemp = this.materialTempService.getByCode(code);
				}
				if(null == materialTemp) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				String pid = materialTemp.getPid();
				if(StringUtils.isBlank(pid)) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				String[] pidArray = StrUtil.split(pid, ",");
				List<IoEntryDTO> dtoList = Lists.newArrayList();
				for(int i = 0; i < pidArray.length; i++) {
					List<IoEntryDTO> entryDtoList = this.scanMapper.getStkIoBillEntryByMesMaterial(pidArray[i], mesId);
					for (IoEntryDTO ioEntryDTO : entryDtoList) {
						String ioType = ioEntryDTO.getIoType();
						if(StrUtil.startWith(ioType, "2")) {
							dtoList.add(ioEntryDTO);
						}
					}
				}
				if(CollUtil.isEmpty(dtoList)) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				BigDecimal theCost = BigDecimal.ZERO;
				BigDecimal theQty = BigDecimal.ZERO;
				for(Iterator<IoEntryDTO> itera = dtoList.iterator(); itera.hasNext();) {
					IoEntryDTO dto = itera.next();
					BigDecimal cost = dto.getCost();
					BigDecimal qty = dto.getQty();
					if(null != cost) {
						theCost = theCost.add(cost);
					}
					if(null != qty) {
						theQty = theQty.add(qty);
					}
				}
				if(BigDecimal.ZERO.compareTo(theQty) >= 0 || BigDecimal.ZERO.compareTo(theCost) >= 0) {
					billEntry.setCost(BigDecimal.ZERO);
					continue;
				}
				BigDecimal qty = billEntry.getQty();
				BigDecimal cost = qty.multiply(theCost).divide(theQty, 2, BigDecimal.ROUND_DOWN);
				billEntry.setCost(cost);
			}
		}
		return entryList;
	}
	
	private class ProcessingOutPercent{
		private String categoryId;
		
		private BigDecimal percent;
		
		public BigDecimal getPercent() {
			return percent;
		}

		public void setPercent(BigDecimal percent) {
			this.percent = percent;
		}

		public String getCategoryId() {
			return this.categoryId;
		}
		
		public void setCategoryId(String categoryId) {
			this.categoryId = categoryId;
		}
	}
}
